use std::{env::{args as env_args, current_exe, set_var}, fs::{remove_dir_all, remove_file}};

use clap::Parser;
use wtask_base::{app::{get_wtask_data_dir, get_wtask_root_dir}, cmd::{file_cp, start_exe_spawn}, error::WResult, export::{log_debug, log_error, log_info}, logs::log_init, update::get_local_version};

#[cfg(unix)]
use wtask_base::cmd::run_cmd_pure;

use wtask_install::{get_install_file, get_remove_version, install_all, uninstall_all, CMDArgs};



fn main() -> WResult<()> {
    let mut args = CMDArgs::parse();
    log_init(&args.log_args);

    if let Some(root) = args.root.clone() {
        unsafe { set_var("WTASK_ROOT", root) };
    }
    
    log_debug!("Get local version ...");
    let version_local = get_local_version();
    log_debug!("Get remote version ...");
    let version_remote = match get_remove_version(&args) {
        Ok(version_remote) => version_remote,
        Err(e) => {
            log_error!("Get remote error: {e}");
            version_local.to_owned()
        }
    };

    // install exe in temp dir
    let p = current_exe()?;
    let dir_temp = get_wtask_data_dir("temp", true)?;
    let p_temp = dir_temp.join(p.file_name().unwrap().to_string_lossy().to_string());
    
    log_debug!("Get Version: {version_local:?} vs {version_remote:?}");

    // no need update
    if version_local.eq(&version_remote) {
        log_info!("Version: {version_local}, No need update, exiting ...");
        if p_temp.exists() {
            remove_file(&p_temp)?;
        }
        return Ok(());
    }
    // run update in temp dir
    if !p.starts_with(&dir_temp) {
        file_cp(&p, &p_temp)?;
        #[cfg(unix)]
        run_cmd_pure(vec!["chmod", "+x", p_temp.to_str().unwrap()], None, None)?;
        log_info!("Running temp install {:?} {} ...", p_temp, p_temp.exists());
        let mut args_iter = env_args().skip(1).collect::<Vec<_>>();
        args_iter.insert(0, p_temp.to_string_lossy().to_string());

        let dir_now = current_exe()?.parent().unwrap().to_string_lossy().to_string();
        let t =  args_iter.iter().enumerate().find(| v | v.1.as_str().eq("--dir"));
        if let Some((i, _)) = t {
            args_iter[i+1] = dir_now;
        } else {
            args_iter.push("--dir".to_owned());
            args_iter.push(dir_now);
        }

        let dir = get_wtask_root_dir();
        start_exe_spawn(&dir, args_iter)?;
        log_info!("Running temp install {p_temp:?}, master exiting ...");
        return Ok(());
    }

    log_info!("Start installing {version_remote} ...");
    args.ver = Some(version_remote.clone());
    
    let file_install = get_install_file(&args)?;
    if let Err(e) = install_all(&file_install) {
        log_error!("Install Fail: {e}");
        let _ = uninstall_all();
    } else {
        if args.dir.is_some() && args.del {
            let d = args.dir.unwrap();
            log_info!("Del {d}");
            let _ = remove_dir_all(d);
        }
        log_info!("Installed: {version_remote:?}, exiting ...");
    }
    
    Ok(())
}